package cn.com.twoke.application.game.mario.game.entity;

import cn.com.twoke.application.game.mario.core.ecs.world.GameWorld;
import cn.com.twoke.application.game.mario.core.ecs.component.ColliderComponent;
import cn.com.twoke.application.game.mario.core.ecs.component.PositionComponent;
import cn.com.twoke.application.game.mario.core.ecs.component.RigidbodyComponent;
import cn.com.twoke.application.game.mario.core.ecs.component.SizeComponent;
import cn.com.twoke.application.game.mario.core.ecs.entity.Entity;
import cn.com.twoke.application.game.mario.game.component.JumpComponent;
import cn.com.twoke.application.game.mario.game.component.PlayerComponent;
import cn.com.twoke.application.game.mario.game.component.PlayerControlComponent;
import cn.com.twoke.application.game.mario.game.component.SceneComponent;
import cn.hutool.core.lang.Opt;

import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.Optional;

public class PlayerBuilder extends AbstractEntityBuilder<PlayerBuilder> {
    private int width;
    private int height;
    private String playerName;
    /**
     * 初始化移动速度
     */
    private Integer initMoveSpeed;
    /**
     * 初始化场景
     */
    private String initSceneName;
    /**
     * 向左移动
     */
    private Integer moveLeftKey;
    /**
     * 向右移动
     */
    private Integer moveRightKey;
    /**
     * 跳跃按键
     */
    private Integer jumpKey;
    /**
     * 下蹲按键
     */
    private Integer downKey;
    /**
     * 攻击按键
     */
    private Integer attackKey;



    public PlayerBuilder(GameWorld world) {
        super(world);
    }

    public PlayerBuilder width(int width) {
        this.width = width;
        return this;
    }

    public PlayerBuilder height(int height) {
        this.height = height;
        return this;
    }

    public PlayerBuilder playerName(String playerName) {
        this.playerName = playerName;
        return this;
    }

    public PlayerBuilder initMoveSpeed(Integer initMoveSpeed) {
        this.initMoveSpeed = initMoveSpeed;
        return this;
    }

    public PlayerBuilder initSceneName(String initSceneName) {
        this.initSceneName = initSceneName;
        return this;
    }

    public PlayerBuilder moveLeftKey(Integer moveLeftKey) {
        this.moveLeftKey = moveLeftKey;
        return this;
    }

    public PlayerBuilder moveRightKey(Integer moveRightKey) {
        this.moveRightKey = moveRightKey;
        return this;
    }


    public PlayerBuilder jumpKey(Integer jumpKey) {
        this.jumpKey = jumpKey;
        return this;
    }


    public PlayerBuilder downKey(Integer downKey) {
        this.downKey = downKey;
        return this;
    }

    public PlayerBuilder attackKey(Integer attackKey) {
        this.attackKey = attackKey;
        return this;
    }


    @Override
    public Entity build() {
        Entity entity = world.createEntity();
        entity.setType(EntityType.PLAYER);
        PositionComponent entityPosition = new PositionComponent(startX, startY);
        SizeComponent entitySize = new SizeComponent(width, height);

        PlayerComponent playerComponent = new PlayerComponent(
                Optional.ofNullable(playerName).orElse("Mario"),
                Optional.ofNullable(initMoveSpeed).orElse(2), false, false, false, false, PlayerComponent
                .Direction.RIGHT);

        entity.addComponent(entityPosition);
        entity.addComponent(entitySize);
        entity.addComponent(playerComponent);
        entity.addComponent(new PlayerControlComponent(
                Opt.ofNullable(moveLeftKey).orElse(KeyEvent.VK_A),
                Opt.ofNullable(moveRightKey).orElse(KeyEvent.VK_D),
                Opt.ofNullable(jumpKey).orElse(KeyEvent.VK_K),
                Opt.ofNullable(downKey).orElse(KeyEvent.VK_S),
                Opt.ofNullable(attackKey).orElse(KeyEvent.VK_SPACE)
        ));
        entity.addComponent(new SceneComponent(initSceneName));
        entity.addComponent(new ColliderComponent(() -> new Rectangle((int)entityPosition.x, (int)entityPosition.y,entitySize.width, entitySize.height)));
        entity.addComponent(new RigidbodyComponent());
        entity.addComponent(new JumpComponent());
        // 扩展操作
        Opt.ofNullable(extend).ifPresent(extend ->  extend.accept(entity));
        return entity;
    }
}
